package com.jz.util;

import com.jz.bean.AppInfoBean;
import com.jz.bean.SynchronizedAppConfigBean;
import org.w3c.dom.Document;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;

public class JAXBUtils {

    public static void main(String[] args) {
        try {
            SynchronizedAppConfigBean et = new SynchronizedAppConfigBean();
            et.setCreateTime(TimeUtil.getTime());
            et.setUpdateTime(TimeUtil.getTime());
//            et.getList().add(new AppInfoBean());
            et.getList().add(new AppInfoBean(false, TimeUtil.getTime(), "启动ZK服务监控"));
            et.getList().add(new AppInfoBean(true, TimeUtil.getTime(), "关闭ZK服务监控"));
            String xml = dtoToXmlString(et);
            System.out.println(xml);
            SynchronizedAppConfigBean temp  = xmlToDto(xml, SynchronizedAppConfigBean.class);
            System.out.println(temp.getCreateTime());
            System.out.println(temp.getUpdateTime());
            System.out.println(temp.getList().get(0).getMessage());
            // DocumentBuilderFactory dbf =
            // DocumentBuilderFactory.newInstance();
            // DocumentBuilder db = dbf.newDocumentBuilder();
            // Document doc = db.parse(System.getProperty("user.dir")
            // + "/conf/expandclass.xml");
            // AirlineLoginConfigBean classes = domToDto(doc,
            // AirlineLoginConfigBean.class);
            // System.out.println(classes);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 对象转变为xml
     *
     * @param <T>
     * @param dto
     * @param xml
     * @throws JAXBException
     * @throws IOException
     */
    public static <T> void dtoToXml(T dto, String xml) throws JAXBException,
            IOException {
        JAXBContext context = JAXBContext.newInstance(dto.getClass());
        Marshaller m = context.createMarshaller();
        OutputStream out = new FileOutputStream(xml);
        m.marshal(dto, out);
        out.close();
    }

    /**
     * xml转换为对象
     *
     * @param <T>
     * @param xml
     * @param clazz
     * @return
     * @throws JAXBException
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public static <T> T xmlToDto(String xml, Class<T> clazz)
            throws JAXBException, IOException {
        JAXBContext context = JAXBContext.newInstance(clazz);
        Unmarshaller um = context.createUnmarshaller();
        InputStream in = new ByteArrayInputStream(xml.getBytes("UTF-8"));
        T t = (T) um.unmarshal(in);
        in.close();
        return t;
    }

    /**
     * xml String 转化为对象
     *
     * @param <T>
     * @param xmlStr
     * @param clazz
     * @return
     * @throws JAXBException
     */
    @SuppressWarnings("unchecked")
    public static <T> T xmlStringToDto(String xmlStr, Class<T> clazz)
            throws JAXBException {
        JAXBContext jc = JAXBContext.newInstance(clazz);
        Unmarshaller u = jc.createUnmarshaller();
        T ret = (T) u.unmarshal(new StreamSource(new StringReader(xmlStr)));
        return ret;
    }

    /**
     * 对象转化为xml String
     *
     * @param <T>
     * @param dto
     * @return
     * @throws JAXBException
     */
    public static <T> String dtoToXmlString(T dto) throws Exception {
        // xml String 转化为对象
        JAXBContext jc = JAXBContext.newInstance(dto.getClass());
        Marshaller m = jc.createMarshaller();
        m.setProperty("jaxb.formatted.output", true);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Result result = new StreamResult(out);
        m.marshal(dto, result);
        return new String(out.toByteArray(),"UTF-8");
    }

    /**
     * 对象转变为byte数组
     *
     * @param <T>
     * @param dto
     * @return
     * @throws JAXBException
     */
    public static <T> byte[] dtoToByteArray(T dto) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(dto.getClass());
        Marshaller m = context.createMarshaller();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        m.marshal(dto, out);
        return out.toByteArray();
    }

    /**
     * byte数组转变为对象
     *
     * @param <T>
     * @param arr
     * @param clazz
     * @return
     * @throws JAXBException
     */
    @SuppressWarnings("unchecked")
    public static <T> T byteArrayToDto(byte[] arr, Class<T> clazz)
            throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(clazz);
        Unmarshaller um = context.createUnmarshaller();
        ByteArrayInputStream in = new ByteArrayInputStream(arr);
        T ret = (T) um.unmarshal(in);
        return ret;
    }

    /**
     * dom转化成dto
     *
     * @param <T>
     * @param dom
     * @param clazz
     * @return
     * @throws JAXBException
     */
    @SuppressWarnings("unchecked")
    public static <T> T domToDto(Document dom, Class<T> clazz)
            throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(clazz);
        Unmarshaller um = context.createUnmarshaller();
        T ret = (T) um.unmarshal(dom);
        return ret;
    }

    /**
     * dto转化成dom
     *
     * @param <T>
     * @param dto
     * @return
     * @throws JAXBException
     * @throws ParserConfigurationException
     */
    public static <T> Document dtoToDom(T dto) throws JAXBException,
            ParserConfigurationException {
        JAXBContext context = JAXBContext.newInstance(dto.getClass());
        Marshaller m = context.createMarshaller();
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.newDocument();
        m.marshal(dto, doc);
        return doc;
    }

    /**
     * dom转化成xml string
     *
     * @param <T>
     * @param dom
     * @param clazz
     * @return
     * @throws JAXBException
     */
    public static <T> String domToString(Document dom, Class<T> clazz)
            throws Exception {
        T dto = domToDto(dom, clazz);
        return dtoToXmlString(dto);
    }

    /**
     * xml string转化成dom
     *
     * @param <T>
     * @param xmlStr
     * @param clazz
     * @return
     * @throws JAXBException
     * @throws ParserConfigurationException
     */
    public static <T> Document stringToDom(String xmlStr, Class<T> clazz)
            throws JAXBException, ParserConfigurationException {
        T dto = xmlStringToDto(xmlStr, clazz);
        return dtoToDom(dto);

    }

}
